import React, { useReducer } from 'react';

const initialState = {number: 0};
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';
const NO_CHANGE = 'NO_CHANGE';

function reducer(state: any,action: any) {
  switch(action.type){
  case INCREMENT:
    return {number: state.number + 1};
  case DECREMENT:
    return {number: state.number - 1};
  case NO_CHANGE:
    return state;
  default:
    return state;
  }
}

/*
  useState 的替代方案。它接收一个形如 (state, action) => newState 的 reducer，并返回当前的 state 以及与其配套的 dispatch 方法

  在某些场景下，useReducer 会比 useState 更适用，例如 state 逻辑较复杂且包含多个子值，或者下一个 state 依赖于之前的 state 等

  具体一点的：比如form表单
*/

function Child(props: any){
  console.log('Child render');
  return <div>{props.data.number}</div>
}

export default function App(){
  const [state, dispatch] = useReducer(reducer, initialState);
  const [state2, dispatch2] = useReducer(reducer, initialState);

  console.log('App render---');
  console.log('initialState:', initialState);
  return (
    <div>
      <p>{state.number}</p>
      <p>{state2.number}</p>
      <button onClick={() => dispatch({type: INCREMENT})}>+</button>
      <button onClick={() => dispatch2({type: DECREMENT})}>-</button>
      {/*如果reducer返回的状态和先前的状态没有区别,那么就不会重新渲染,但注意这里如果 先点击+ 再点击不变 那会重新渲染一次(不会渲染孩子 点击后看dev-tool的html 应该是整个ui都不会渲染 包括非子组件的部分 比如上面的<p>{state.number}</p> 不排除还是经过了diff)*/}
      <button onClick={() => dispatch2({type: NO_CHANGE})}>不变</button>
      <Child data={state}/>
    </div>
  );
}
